package com.bing.bean.weixin;

import com.bing.bean.WeiXinUser;
import com.bing.utils.CommonUtils;
import com.bing.utils.HttpUtils;
import org.apache.commons.codec.CharEncoding;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * Created by kaibb on 2014/11/29.
 */

@Service
public class OauthInfo {

    private static final Logger logger = LoggerFactory.getLogger(OauthInfo.class);
    @Value("${weixin.appid}")
    private String appId;
    @Value("${weixin.appsecret}")
    private String appsecret;
    private String redirect_uri;
    private String response_type = "code";
    @Value("${weixin.scope:snsapi_base}")
    private String scope ;
    @Value("${weixin.state:88888888}")
    private String state ;
    @Value("${weixin.grant_type:authorization_code}")
    private String grant_type ;
    private String GET_CODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=%s&scope=%s&state=%s#wechat_redirect";

    private String GET_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=%s";

    private String GET_USER_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";

    public String getCodeUrl() {
        String codeUrl = String.format(GET_CODE_URL, appId, redirect_uri, response_type, scope, state);
        logger.info("获取CodeUrl:{}",codeUrl);
        return codeUrl;
    }

    public String getAppId() {
        return appId;
    }

    public String getAppsecret() {
        return appsecret;
    }

    public String getRedirect_uri() {
        return redirect_uri;
    }

    public String getResponse_type() {
        return response_type;
    }

    public String getScope() {
        return scope;
    }

    public String getState() {
        return state;
    }

    public String getGrant_type() {
        return grant_type;
    }

    public String getTokenUrl(String code) {
        String tokenUrl = String.format(GET_TOKEN_URL, appId, appsecret, code, grant_type);
        logger.info("获取tokenUrl:{}",tokenUrl);
        return tokenUrl;
    }

    public String getUserUrl(String token, String openid) {
        String userUrl = String.format(GET_USER_URL, token, openid);
        logger.info("获取userUrl:{}",userUrl);
        return userUrl;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public void setAppsecret(String appsecret) {
        this.appsecret = appsecret;
    }

    public void setGrant_type(String grant_type) {
        this.grant_type = grant_type;
    }

    public void setRedirect_uri(String redirect_uri) {
        logger.info("设置回调地址:{}", redirect_uri);
        try {
            redirect_uri = URLEncoder.encode(redirect_uri, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error("编码回调网址失败:{}", redirect_uri, e);
        }
        this.redirect_uri = redirect_uri;
    }

    public void setResponse_type(String response_type) {
        this.response_type = response_type;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public void setState(String state) {
        this.state = state;
    }


    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("OauthInfo{");
        sb.append("appId='").append(appId).append('\'');
        sb.append(", appsecret='").append(appsecret).append('\'');
        sb.append(", redirect_uri='").append(redirect_uri).append('\'');
        sb.append(", response_type='").append(response_type).append('\'');
        sb.append(", scope='").append(scope).append('\'');
        sb.append(", state='").append(state).append('\'');
        sb.append(", grant_type='").append(grant_type).append('\'');
        sb.append('}');
        return sb.toString();
    }

    @Cacheable(value = "oauth_cache", key = "#code", unless = "#result!=null")
    public WeiXinUser oauthWeiXin(String code) {
        HttpClient client = HttpUtils.createSSLClientDefault();
        String getTokenUrl = getTokenUrl(code);
        logger.info("请求token Url:{} ", getTokenUrl);
        HttpGet httpget = new HttpGet(getTokenUrl);
//执行get请求.
        HttpResponse responses = null;
        WeiXinUser weiXinUser = null;
        try {
            responses = client.execute(httpget);
            HttpEntity entity = responses.getEntity();
            String out = EntityUtils.toString(entity, CharEncoding.UTF_8);
            logger.info("获取token:{}", out);
            AccessToken accessToken = CommonUtils.GSON.fromJson(out, AccessToken.class);
            logger.info("解析token:{}", accessToken.toString());
            if (StringUtils.isEmpty(accessToken.getOpenid())) {
                return weiXinUser;
            }
            String userInfo = getUserUrl(accessToken.getAccess_token(), accessToken.getOpenid());
            httpget = new HttpGet(userInfo);
            logger.info("请求用户信息url:{} ", userInfo);
            responses = client.execute(httpget);
//获取响应实体
            entity = responses.getEntity();
            out = EntityUtils.toString(entity, CharEncoding.UTF_8);
            logger.info("获取用户信息:{}", out);
            weiXinUser = CommonUtils.GSON.fromJson(out, WeiXinUser.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return weiXinUser;
    }
}
